﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WCAD
{
    public static class BmBlcokMethod
    {
        public static bool GetBlockTableRecordByName(string name, out BlockTableRecord btr)
        {
            btr = null;
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
                foreach (ObjectId item in bt)
                {
                    BlockTableRecord btrr = item.GetObject(OpenMode.ForRead) as BlockTableRecord;
                    if (btrr.Name == name)
                    {
                        btr = btrr;
                        return true;
                    }
                }
            }
            return false;
        }
        public static BlockReference InsertAttrBlockReference(Point3d position, ObjectId blockRecordId)
        {
            BlockReference br = new BlockReference(position, blockRecordId);
            Database db = HostApplicationServices.WorkingDatabase;
            CADCommand cADCommand = new CADCommand();
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)db.BlockTableId.GetObject(OpenMode.ForWrite);
                if (bt.Has(blockRecordId))
                {
                    BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite);
                    btr.AppendEntity(br);
                    BlockTableRecord blockRecord = (BlockTableRecord)blockRecordId.GetObject(OpenMode.ForWrite);
                    trans.AddNewlyCreatedDBObject(br, true);
                    if (blockRecord.HasAttributeDefinitions)
                    {
                        foreach (ObjectId item in blockRecord)
                        {
                            DBObject obj = item.GetObject(OpenMode.ForWrite);
                            if (obj is AttributeDefinition)
                            {
                                AttributeReference attrRef = new AttributeReference();
                                //声明属性参照
                                AttributeDefinition ad = (AttributeDefinition)obj;
                                if (ad.Tag.Contains("X"))
                                {
                                    string str = @"%<\AcObjProp Object(%<\_ObjId " + br.ObjectId.ToString().TrimStart('(').TrimEnd(')') + @">%,1).InsertionPoint \f ""%lu2%pt2%pr4"">%";
                                    Field field1 = new Field(str);
                                    //attrRef.SetAttributeFromBlock(ad, br.BlockTransform);
                                    attrRef = new AttributeReference(ad.Position, "", ad.Tag, ad.TextStyleId);
                                    attrRef.TransformBy(br.BlockTransform);
                                    attrRef.TextString = "";
                                    attrRef.SetField(field1);
                                    //str1 = attrRef.getTextWithFieldCodes();

                                }
                                else
                                {
                                    bool bb = ad.HasFields;
                                    attrRef.SetAttributeFromBlock(ad, br.BlockTransform);
                                }


                                br.AttributeCollection.AppendAttribute(attrRef);
                                trans.AddNewlyCreatedDBObject(attrRef, true);
                                if (attrRef.Tag.Contains("X"))
                                {

                                    //br.ObjectId.GetObject(OpenMode.ForWrite);
                                    //attrRef.ObjectId.GetObject(OpenMode.ForWrite);

                                    //try
                                    //{

                                    //    attrRef.SetField(field);
                                    //}
                                    //catch (Exception ex ) 
                                    //{

                                    //    throw;
                                    //}

                                }
                            }
                        };
                    }
                }
                trans.Commit();
            }
            return br;
        }



        public static void UpdateAtt(BlockReference block, Dictionary<string, string> keyValues)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                block.ObjectId.GetObject(OpenMode.ForRead);
                foreach (ObjectId id in block.AttributeCollection)
                {
                    AttributeReference att = id.GetObject(OpenMode.ForWrite) as AttributeReference;
                    if (keyValues.ContainsKey(att.Tag))
                    {

                        att.TextString = keyValues[att.Tag];


                    }
                }
                trans.Commit();
            }
        }
        public static Database Wblock(List<Entity> entities, Point3d point)
        {
            ObjectIdCollection ids = new ObjectIdCollection(entities.Select(x => x.ObjectId).ToArray());
            Database db = HostApplicationServices.WorkingDatabase;
            Point3d point1 = db.Insbase;
            Database database = db.Wblock(ids, point);
            Point3d point2 = database.Insbase;
            return database;
        }
        public static void InsertDwg(string sourceFileName, string name, bool isDelete = false)
        {
            Database database = new Database(false, true);
            if (!System.IO.File.Exists(sourceFileName)) return;
            database.ReadDwgFile(sourceFileName, FileShare.Read, true, null);
            Database db = HostApplicationServices.WorkingDatabase;
            ObjectId objid = db.Insert(name, database, true);
            if (isDelete)
            {
                using (Transaction tran = db.TransactionManager.StartTransaction())
                {
                    BlockTableRecord btr = objid.GetObject(OpenMode.ForWrite) as BlockTableRecord;
                    btr.Erase();
                    tran.Commit();
                }
            }
        }
        public static List<Entity> ExplodeBlockReference(BlockReference block)
        {
            DBObjectCollection dbs = new DBObjectCollection();
            block.Explode(dbs);
            List<Entity> entities = new List<Entity>();
            foreach (Entity item in dbs)
            {
                entities.Add(item);
            }
            return entities;
        }
        /// <summary>
        /// 设置动态块的动态属性
        /// </summary>
        /// <param name="blockId">动态块的ObjectId</param>
        /// <param name="propName">动态属性的名称</param>
        /// <param name="value">动态属性的值</param>
        public static void SetDynBlockValue(BlockReference block, Dictionary<string, double> propNameValues)
        {
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                block.ObjectId.GetObject(OpenMode.ForWrite);
                DynamicBlockReferencePropertyCollection dynProperties = block.DynamicBlockReferencePropertyCollection;

                foreach (DynamicBlockReferenceProperty property in dynProperties)
                {
                    if (property.ReadOnly || property.PropertyName == "Origin")
                    {
                        continue;
                    }
                    string name = property.PropertyName;
                    if (propNameValues.ContainsKey(name))
                    {
                        property.Value = propNameValues[name];
                    }
                }
                trans.Commit();
            }
        }
        public static void SetDynBlockValue(BlockReference block, string name,double value)
        {
            Dictionary<string, double> keyValuePairs = new Dictionary<string, double>();
            keyValuePairs.Add(name, value);
            SetDynBlockValue(block, keyValuePairs);
        }

        public static Extents3d GetBlockExtents3d(BlockReference block)
        {
            DBObjectCollection dbs = new DBObjectCollection();
            block.Explode(dbs);
            var ss = dbs.ToEntities<Entity>();
            Extents3d extents = EmEntityMethod.GetExtents3d(ss);
            return extents;
        }
    }
}
